package com.chuang.bootplus.service.impl;

import cn.hutool.crypto.SecureUtil;
import cn.hutool.system.UserInfo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.chuang.bootplus.base.exception.BusException;
import com.chuang.bootplus.base.utils.ApiResponse;
import com.chuang.bootplus.base.utils.BeanUtil;
import com.chuang.bootplus.base.utils.JwtUtil;
import com.chuang.bootplus.base.utils.MD5Util;
import com.chuang.bootplus.config.shiro.JwtToken;
import com.chuang.bootplus.entity.User;
import com.chuang.bootplus.mapper.UserMapper;
import com.chuang.bootplus.po.LoginCodePO;
import com.chuang.bootplus.po.LoginPO;
import com.chuang.bootplus.po.SignInPO;
import com.chuang.bootplus.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chuang.bootplus.vo.UserInfoVO;
import lombok.RequiredArgsConstructor;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.ExpiredCredentialsException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.xml.transform.Result;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author ${author}
 * @since 2021-11-04
 */
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    JwtUtil jwtUtils;

    @Override
    public ApiResponse<UserInfoVO> login(LoginPO po , HttpServletResponse response) {
        User user =getOne(new QueryWrapper<User>().eq("username", po.getUsername()));
        if(user == null){
           throw new BusException("用户不存在");
       }
        if(!user.getPassword().equals(MD5Util.easyMd5(po.getPassword()))) {
           throw new BusException("用户密码错误");
        }
        String jwt = jwtUtils.generateToken(user.getId());
        response.setHeader("Authorization", jwt);
        response.setHeader("Access-Control-Expose-Headers", "Authorization");
        UserInfoVO userInfoVO = BeanUtil.beanA2beanB(user, UserInfoVO.class);
        // 用户可以另一个接口
        return new ApiResponse<>(userInfoVO).setToken(jwt);
    }



    @Override
    public ApiResponse<Void> signIn(SignInPO po ) {
        if (getOne(new LambdaQueryWrapper<User>().eq(User::getUsername, po.getUsername())) != null) {
            throw new BusException("该用户名已被注册");
        }
        String salt = "matrix";
        String pass = MD5Util.easyMd5(po.getPassword());
        User user = BeanUtil.beanA2beanB(po, User.class);
        user.setPassword(pass);
        remove(new LambdaQueryWrapper<User>().eq(User::getPhone, po.getPhone()));
        save(user);
        return new ApiResponse<>();
    }

    @Override
    public ApiResponse<UserInfoVO> loginPhone(LoginCodePO po , HttpServletResponse response) {
        /*
        * 不能用手机号作为验证，因为在发送验证码的时候为了存储验证码，将手机号也存储进去了，所以拿手机号无法验证该手机号是否真正被注册
        * */
        User user =getOne(new QueryWrapper<User>().eq("phone", po.getPhone()));
        if(user.getUsername()==null){
            removeById(user.getId());   //说明这个user的添加是通过发验证码来添加的，不是真正注册的
            throw new BusException("用户不存在");
        }
        if(!user.getCode().equals(po.getCode())) {
            throw new BusException("验证码错误");
        }
        String jwt = jwtUtils.generateToken(user.getId());
        response.setHeader("Authorization", jwt);
        response.setHeader("Access-Control-Expose-Headers", "Authorization");

        UserInfoVO userInfoVO = BeanUtil.beanA2beanB(user, UserInfoVO.class);
        // 用户可以另一个接口
        return new ApiResponse<>(userInfoVO).setToken(jwt);
    }

    @Override
    public ApiResponse<Void> logout() {
        SecurityUtils.getSubject().logout();
        return new ApiResponse<>();
    }


}
